package com.fafu.mq.mqserver.core;

import lombok.Data;

import java.io.Serializable;
import java.util.UUID;

/**
 * 表示一个要进行传递的消息
 * 此处的 Message 是要在网络中传输, 并且能够写入文件
 * 需要针对 Message 进行序列化和反序列化.
 * 此处使用标准库自带的 序列化和反序列化 操作
 */

@Data
public class Message implements Serializable {

    private static final long serialVersionUID = 1L;
    //核心部分
    private BasicProperties basicProperties = new BasicProperties();
    public byte[] body;

    //辅助属性
    //Message 持久化的时候会存储到文件中去
    //一个文件会存储很多的消息
    //使用以下的偏移量来找到位置[offsetBeg,offsetEnd)
    //这两个属性不需要被序列化保存到文件中, 使用 transient 防止被序列化
    private transient long offsetBeg = 0;//消息数据的开头距离文件开头位置的偏移量(字节)
    private transient long offsetEnd = 0;//消息数据的结尾距离文件开头的位置的偏移量(字节)

    //该消息在文件中是否是有效消息(逻辑删除)
    //0x1 表示有效, 0x0表示无效
    private byte isValid= 0x1;

    //使用工厂方法, 让工厂方法帮我们封装一下创建 Message 对象的过程
    //会生成唯一的MessageId

    public static Message createMessageWithId(BasicProperties basicProperties,byte[] body,String routingKey){
        Message message = new Message();
        //不为空才附上, 防止异常
        if(basicProperties != null){
            message.setBasicProperties(basicProperties);
        }
        //生成的 Id 以 M- 为前缀
        message.setMessageId("M-" + UUID.randomUUID());
        message.setRoutingKey(routingKey);//如果发生冲突, 优先选择外面的
        message.body = body;
        //此处先设置 body 和 basicProperties , 这两个是核心
        //后三个是消息持久化才使用, 后面再进行设定
        return message;
    }

    public String getMessageId(){
        //为防止空指针在上面 new 一个对象
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId){
        //为防止空指针在上面 new 一个对象
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey(){
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey){
        basicProperties.setRoutingKey(routingKey);
    }

    public Integer getDeliverMode(){
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(Integer deliverMode){
        basicProperties.setDeliverMode(deliverMode);
    }
}
